#pragma once
#include <sys/epoll.h>
#include <cstdlib>
#include <unistd.h>
#include <iostream>
#include "logmessage.hpp"
#include "nocopy.hpp"

using namespace std;

class Epoller: public NoCopy
{
    static const int TIMEOUT = 5000;
    int _epfd = -1;

public:

    static const int SIZE = 128;

    Epoller()
    {
        _epfd = epoll_create(SIZE);
        if (_epfd == -1)
        {
            LogMessage(Error, "epoll_create error! code: %d", errno);
            exit(errno);
        }
        LogMessage(Debug, "epoll create success!");
    }

    int EpollCtrl(int op, int sockfd, uint32_t events)
    {
        int ret = -1;
        if (op == EPOLL_CTL_DEL)
        {
            ret = epoll_ctl(_epfd, op, sockfd, nullptr);
        }
        else
        {
            epoll_event epevent;
            epevent.events = events;
            epevent.data.fd = sockfd;
            ret = epoll_ctl(_epfd, op, sockfd, &epevent);
        }
        if(ret == -1)
            LogMessage(Error, "epoll_ctl error! code: %d", errno);
        else    
            LogMessage(Debug, "epoll_ctl success! op:%d sockfd:%d", op, sockfd);
        return ret;
    }

    int EpollWait(epoll_event events[], int maxevents)
    {
        int n = epoll_wait(_epfd, events, maxevents, TIMEOUT);
        if(n == 0)
        {
            cout << "timeout!" << endl;
        }
        else if(n == -1)
        {
            LogMessage(Error, "epoll_wait error! code: %d", errno);
        }
        return n;
    }

    ~Epoller()
    {
        if (_epfd != -1)
        {
            close(_epfd);
        }
    }
};